
#include "semantics_method.h"
//#include "semantics_expression.h"

#include "generic_table.cpp"

#include "main_container.h"
#include "errors_warnings.h"
extern MainContainer * CompilerData;


SemanticsMethod::SemanticsMethod()
{
	this->parentContext = -1;

	this->IsConstructor = false;
	this->IsContinuous = false;
	this->IsDiscrete = false;
	this->IsNumeric = false;
	this->IsReadProperty = false;
	this->IsWriteProperty = false;

	this->ModifierAbstract = false;
	this->ModifierFinal = false;
	this->ModifierOverride = false;
	this->ModifierPrivate = false;
	this->ModifierProtected = false;
	this->ModifierPublic = false;
	this->ModifierStatic = false;
	this->ModifierVirtual = false;

	this->HasMinusINF = false;
	this->HasPlusINF = false;

	this->Name = new GenericTable<int>();
	this->DataType = new SemanticsDataType();
	this->ConstructorInherit = new SemanticsMethodStatementMethodCall();
	this->ValuePairs = new GenericTable<SemanticsMethodValuePair>();
	this->Parameters = new GenericTable<SemanticsMethodParameter>();
	this->MethodBody = new SemanticsMethodBody();

}


SemanticsMethod::~SemanticsMethod()
{
	if(Name != NULL)
	{
		delete Name;
		Name = NULL;
	}

	if(DataType != NULL)
	{
		delete DataType;
		DataType = NULL;
	}

	if(ConstructorInherit != NULL)
	{
		delete ConstructorInherit;
		ConstructorInherit = NULL;
	}

	if(ValuePairs != NULL)
	{
		delete ValuePairs;
		ValuePairs = NULL;
	}

	if(Parameters != NULL)
	{
		delete Parameters;
		Parameters = NULL;
	}

	if(MethodBody != NULL)
	{
		delete MethodBody;
		MethodBody = NULL;
	}
}



SemanticsMethodBody::SemanticsMethodBody()
{
	this->Body = new GenericTable<SemanticsMethodStatement>();
	this->LocalVariables = new GenericTable<SemanticsField>();

}
SemanticsMethodBody::~SemanticsMethodBody()
{
}

SemanticsMethodParameter::SemanticsMethodParameter()
{
	this->ModifierConst = false;
	this->DataType = new SemanticsDataType();
	this->Name = new GenericTable<int>();
}


SemanticsMethodParameter::~SemanticsMethodParameter()
{

}


/*#ifdef DEBUG
void SemanticsMethod::DebugXMLOutput(FILE * fo)
{
	// TODO
}
#endif
*/

//int Label; 
//SemanticsMethodStatementType Type;
#ifdef DEBUG
void SemanticsMethodStatement::DebugXMLOutput(FILE * fo)
{
	//start tag
	fprintf(fo, "<semanticsMethodStatement label=\"%d\" type=\"", this->Label);

	//write Type
	switch (this->Type)
	{
	case MetStatAssignment:
		fprintf(fo,"MetStatAssignment");
		break;
	case MetStatMethodCall:
		fprintf(fo,"MetStatMethodCall");
		break;
	case MetStatIf:
		fprintf(fo,"MetStatIf");
		break;
	case MetStatWhile:
		fprintf(fo,"MetStatWhile");
		break;
	case MetStatFor:
		fprintf(fo,"MetStatFor");
		break;
	case MetStatDoWhile:
		fprintf(fo,"MetStatDoWhile");
		break;
	case MetStatSwitchCase:
		fprintf(fo,"MetStatSwitchCase");
		break;
	case MetStatBreak:
		fprintf(fo, "MetStatBreak");
		break;
	case MetStatContinue:
		fprintf(fo,"MetStatContinue");
		break;
	case MetStatGoto:
		fprintf(fo,"MetStatGoto");
		break;
	case MetStatReturn:
		fprintf(fo,"MetStatReturn");
		break;
	case MetStatStart:
		fprintf(fo,"MetStatStart");
		break;
	case MetStatStop:
		fprintf(fo,"MetStatStop");
		break;
	case MetStatDerivationAssignment:
		fprintf(fo,"MetStatDerivationAssignment");
		break;
	}

	fprintf(fo,"\">\n");

	//end tag
	fprintf(fo, "</semanticsMethodStatement>\n");
}
#endif

//GenericTable<SemanticsField> * LocalVariables;
//GenericTable<SemanticsMethodStatement> * Body;
#ifdef DEBUG
void SemanticsMethodBody::DebugXMLOutput(FILE * fo)
{
	//start tag
	fprintf(fo,"<semanticsMethodBody>\n");


	//localVariables
	fprintf(fo,"<localVariables>\n");

	for(int i = 0; i < this->LocalVariables->GetCount(); i++)
	{
		SemanticsField * sf = this->LocalVariables->GetData(i);
		sf->DebugXMLOutput(fo);
	}

	fprintf(fo,"</localVariables>\n");


	//body
	fprintf(fo,"<body>\n");
	for(int i = 0; i < this->Body->GetCount(); i++)
	{
		SemanticsMethodStatement *sms = this->Body->GetData(i);
		sms->DebugXMLOutput(fo);
	}

	fprintf(fo,"</body>\n");

	//end tag
	fprintf(fo,"</semanticsMethodBody>\n");    
}
#endif



//bool IsDeclaration;
//GenericTable<int> * DataTypeName;
//GenericTable<int> * LValue;
//SemanticsExpression * RValue;
#ifdef DEBUG
void SemanticsMethodStatementAssignment::DebugXMLOutput(FILE * fo){

	//strat tag
	fprintf(fo,"<semanticsMethodStatementAssignment isDeclaration=\"");
	if (IsDeclaration)
		fprintf(fo,"true");
	else 
		fprintf(fo,"false");
	fprintf(fo,"\">\n");


	//call base
	SemanticsMethodStatement::DebugXMLOutput(fo);

	//tables
	SemanticAnalyzer::DebugOutputNameFromTable(fo, this->DataTypeName, CompilerData->Units);
	SemanticAnalyzer::DebugOutputNameFromTable(fo, this->LValue, CompilerData->Units);


	RValue->DebugXMLOutput("rValue",fo);



	//end tag
	fprintf(fo,"</semanticsMethodStatementAssignment>");
}
#endif



//GenericTable<int> * Name;
//GenericTable<SemanticsExpression> * Arguments;
#ifdef DEBUG
void SemanticsMethodStatementMethodCall::DebugXMLOutput(FILE * fo){

	//start tag
	fprintf(fo,"<semanticsMethodStatementMethodCall>\n");

	//call base
	SemanticsMethodStatement::DebugXMLOutput(fo);

	//names
	SemanticAnalyzer::DebugOutputNameFromTable(fo, this->Name, CompilerData->Units);


	//Arguments
	fprintf(fo,"<arguments>\n");

	for(int i = 0; i < this->Arguments->GetCount(); i++)
	{
		SemanticsExpression * se = this->Arguments->GetData(i);
		se->DebugXMLOutput(fo);
	}		

	fprintf(fo,"</arguments>\n");



	//end tag
	fprintf(fo,"</semanticsMethodStatementMethodCall>\n");

}
#endif


//SemanticsExpression * Expression;
//SemanticsMethodBody * BodyIf;
//SemanticsMethodBody * BodyElse;
#ifdef DEBUG
void SemanticsMethodStatementIf::DebugXMLOutput(FILE * fo){

	//start tag
	fprintf(fo,"<semanticsMethodStatementIf>\n");

	//call base
	SemanticsMethodStatement::DebugXMLOutput(fo);


	//Expression
	Expression->DebugXMLOutput(fo);
	//BodyIf
	BodyIf->DebugXMLOutput(fo);
	//BodyElse
	BodyElse->DebugXMLOutput(fo);


	//end tag
	fprintf(fo,"</semanticsMethodStatementIf>\n");

}
#endif


//SemanticsExpression * Expression;
//SemanticsMethodBody * LoopBody;
#ifdef DEBUG
void SemanticsMethodStatementWhile::DebugXMLOutput(FILE * fo){

	//start tag
	fprintf(fo,"<semanticsMethodStatementWhile>\n");

	//call base
	SemanticsMethodStatement::DebugXMLOutput(fo);


	//Expression
	Expression->DebugXMLOutput(fo);
	//LoopBody
	LoopBody->DebugXMLOutput(fo);



	//end tag
	fprintf(fo,"</semanticsMethodStatementWhile>\n");

}
#endif


//SemanticsMethodStatement * InitializationStatement;
//SemanticsExpression * Expression;
//SemanticsMethodStatement * RepeatStatement;
//SemanticsMethodBody * LoopBody;
#ifdef DEBUG
void SemanticsMethodStatementFor::DebugXMLOutput(FILE * fo){

	//start tag
	fprintf(fo,"<semanticsMethodStatementFor>\n");

	//call base
	SemanticsMethodStatement::DebugXMLOutput(fo);


	//InitializationStatement
	InitializationStatement->DebugXMLOutput(fo);
	//Expression
	Expression->DebugXMLOutput(fo);
	//RepeatStatement
	RepeatStatement->DebugXMLOutput(fo);
	//LoopBody
	LoopBody->DebugXMLOutput(fo);



	//end tag
	fprintf(fo,"</semanticsMethodStatementFor>\n");

}
#endif




//SemanticsMethodBody * LoopBody;
//SemanticsExpression * Expression;
#ifdef DEBUG
void SemanticsMethodStatementDoWhile::DebugXMLOutput(FILE * fo){

	//start tag
	fprintf(fo,"<semanticsMethodStatementDoWhile>\n");

	//call base
	SemanticsMethodStatement::DebugXMLOutput(fo);


	//LoopBody
	LoopBody->DebugXMLOutput(fo);
	//Expression
	Expression->DebugXMLOutput(fo);



	//end tag
	fprintf(fo,"</semanticsMethodStatementDoWhile>\n");

}
#endif



//SemanticsExpression * Expression;
//SemanticsMethodBody * CaseBody;
#ifdef DEBUG
void SemanticsMethodStatementCase::DebugXMLOutput(FILE * fo){

	//start tag
	fprintf(fo,"<semanticsMethodStatementCase>\n");

	//call base
	SemanticsMethodStatement::DebugXMLOutput(fo);


	//Expression
	Expression->DebugXMLOutput(fo);
	//CaseBody
	CaseBody->DebugXMLOutput(fo);


	//end tag
	fprintf(fo,"</semanticsMethodStatementCase>\n");
}
#endif



//GenericTable<SemanticsMethodStatementCase> * Cases;
//SemanticsMethodBody * LoopBody;
//SemanticsExpression * Expression;
#ifdef DEBUG
void SemanticsMethodStatementSwitchCase::DebugXMLOutput(FILE * fo){

	//start tag
	fprintf(fo,"<semanticsMethodStatementSwitchCase>\n");

	//call base
	SemanticsMethodStatement::DebugXMLOutput(fo);


	//start cases
	fprintf(fo,"<cases>\n");

	for(int i = 0; i < this->Cases->GetCount(); i++)
	{
		SemanticsMethodStatementCase * smc = this->Cases->GetData(i);
		smc->DebugXMLOutput(fo);
	}	

	//end cases
	fprintf(fo,"</cases>\n");


	//LoopBody
	LoopBody->DebugXMLOutput(fo);
	//Expression
	Expression->DebugXMLOutput(fo);

	//end tag
	fprintf(fo,"</semanticsMethodStatementSwitchCase>\n");
}
#endif





#ifdef DEBUG
void SemanticsMethodStatementBreak::DebugXMLOutput(FILE * fo){

	//start tag
	fprintf(fo,"<semanticsMethodStatementBreak>\n");

	//call base
	SemanticsMethodStatement::DebugXMLOutput(fo);


	//end tag
	fprintf(fo,"</semanticsMethodStatementBreak>\n");
}
#endif





#ifdef DEBUG
void SemanticsMethodStatementContinue::DebugXMLOutput(FILE * fo){

	//start tag
	fprintf(fo,"<semanticsMethodStatementContinue>\n");

	//call base
	SemanticsMethodStatement::DebugXMLOutput(fo);



	//end tag
	fprintf(fo,"</semanticsMethodStatementContinue>\n");
}
#endif



//GenericTable<int> * Name;
#ifdef DEBUG
void SemanticsMethodStatementGoto::DebugXMLOutput(FILE * fo){

	//start tag
	fprintf(fo,"<semanticsMethodStatementGoto>\n");

	//call base
	SemanticsMethodStatement::DebugXMLOutput(fo);

	//names
	SemanticAnalyzer::DebugOutputNameFromTable(fo, this->Name, CompilerData->Units);



	//end tag
	fprintf(fo,"</semanticsMethodStatementGoto>\n");

}
#endif




//SemanticsExpression * Expression;
#ifdef DEBUG
void SemanticsMethodStatementReturn::DebugXMLOutput(FILE * fo){
    
	//start tag
	fprintf(fo,"<semanticsMethodStatementReturn>\n");

	//call base
	SemanticsMethodStatement::DebugXMLOutput(fo);


	//Expression
	Expression->DebugXMLOutput(fo);



	//end tag
	fprintf(fo,"</semanticsMethodStatementReturn>\n");

}
#endif





//GenericTable<int> * Name;
//SemanticsExpression * Expression; 
#ifdef DEBUG
void SemanticsMethodStartAssignment::DebugXMLOutput(FILE * fo){

	//start tag
	fprintf(fo,"<semanticsMethodStartAssignment>\n");


	//Name
	SemanticAnalyzer::DebugOutputNameFromTable(fo, this->Name, CompilerData->Units);
	//Expression
	Expression->DebugXMLOutput(fo);


	//end tag
	fprintf(fo,"</semanticsMethodStartAssignment>\n");
}
#endif




//GenericTable<int> *Name;
//GenericTable<SemanticsExpression> * Parameters;
//bool HasWithPart;
//GenericTable<SemanticsMethodStartAssignment> * WithAssignments;
#ifdef DEBUG
void SemanticsMethodStatementStart::DebugXMLOutput(FILE * fo){

	//start tag
	fprintf(fo,"<semanticsMethodStatementStart hasWithPart=\"");

	/// ne znam dali HasWithPart treba u pocetni tag ili ne ???
	if (HasWithPart)
		fprintf(fo,"true");
	else 
		fprintf(fo,"false");
	//end start tag
	fprintf(fo,"\">\n");


	//call base
	SemanticsMethodStatement::DebugXMLOutput(fo);



	//Name
	SemanticAnalyzer::DebugOutputNameFromTable(fo, this->Name, CompilerData->Units);

	//start Parameters
	fprintf(fo,"<parameters>\n");

	for (int i = 0; i< this->Parameters->GetCount(); i++)
	{
		SemanticsExpression * se = this->Parameters->GetData(i);
		se->DebugXMLOutput(fo);
	}

	//end Parameters
	fprintf(fo,"</parameters>\n");


    
	//start WithAssignments
	fprintf(fo,"<withAssignments>\n");

	for (int i = 0; i< this->WithAssignments->GetCount(); i++)
	{
		SemanticsMethodStartAssignment * smsa = this->WithAssignments->GetData(i);
		smsa->DebugXMLOutput(fo);
	}

	//end WithAssignments
	fprintf(fo,"</withAssignments>\n");



	//end zag
	fprintf(fo,"</semanticsMethodStatementStart>\n");

}
#endif





//GenericTable<int> *Name;
#ifdef DEBUG
void SemanticsMethodStatementStop::DebugXMLOutput(FILE * fo){

	//start tag
	fprintf(fo,"<semanticsMethodStatementStop>\n");

	//call base
	SemanticsMethodStatement::DebugXMLOutput(fo);


	//name
	SemanticAnalyzer::DebugOutputNameFromTable(fo, this->Name, CompilerData->Units);


	//end tag
	fprintf(fo,"</semanticsMethodStatementStop>\n");

}
#endif



//GenericTable <int> * LValue;
//SemanticsExpression * RValue;
#ifdef DEBUG
void SemanticsMethodStatementDerivationAssignment::DebugXMLOutput(FILE * fo){

	//start tag
	fprintf(fo,"<semanticsMethodStatementDerivationAssignment>\n");

	//call base
	SemanticsMethodStatement::DebugXMLOutput(fo);
	

	//LValue
	SemanticAnalyzer::DebugOutputNameFromTable(fo, this->LValue, CompilerData->Units);


	//RValue
	RValue->DebugXMLOutput("rValue",fo);



	//end tag
	fprintf(fo,"</semanticsMethodStatementDerivationAssignment>\n");

}
#endif



//bool ModifierConst;
//SemanticsDataType * DataType;
//GenericTable<int> * Name;
#ifdef DEBUG
void SemanticsMethodParameter::DebugXMLOutput(FILE * fo)
{

	//start tag
	fprintf(fo,"<semanticsMethodParameter modifierConst=\"");
	if (ModifierConst)
		fprintf(fo,"true");
	else 
		fprintf(fo,"false");
	//end of start tag
	fprintf(fo,"\">\n");


	//DataType
	DataType->DebugXMLOutput(fo);

	//name
	SemanticAnalyzer::DebugOutputNameFromTable(fo, this->Name, CompilerData->Units);



	//end tag
	fprintf(fo,"</semanticsMethodParameter>\n");
	
}
#endif





//bool minusParameterSign;
//bool minusValueSign;
//int Parameter;
//int Value;
#ifdef DEBUG
void SemanticsMethodValuePair::DebugXMLOutput(FILE * fo){

	//start tag
	fprintf(fo,"<semanticsMethodValuePair>\n");

	//minusParameterSign
	fprintf(fo,"<minusParameterSign>\n");
	if (minusParameterSign)
		fprintf(fo,"true");
	else 
		fprintf(fo,"false");
	fprintf(fo,"</minusParameterSign>\n");

    
	//minusValueSign
	fprintf(fo,"<minusValueSign>\n");
	if (minusValueSign)
		fprintf(fo,"true");
	else 
		fprintf(fo,"false");
	fprintf(fo,"</minusValueSign>\n");


	//Parameter
	fprintf(fo,"<parameter>%d</parameter>",this->Parameter);
	
	//Value
	fprintf(fo,"<value>%d</value>",this->Value);



	//end tag
	fprintf(fo,"</semanticsMethodValuePair>\n");

	
}
#endif





//	int parentContext;

//	bool ModifierPrivate;
//	bool ModifierPublic;
//	bool ModifierProtected;
//	bool ModifierStatic;
//	bool ModifierAbstract;
//	bool ModifierFinal;
//	bool ModifierVirtual;
//	bool ModifierOverride;


//	bool IsConstructor;
//	bool IsReadProperty;
//	bool IsWriteProperty;

//	bool IsNumeric;
//	bool IsDiscrete;
//	bool IsContinuous;

//	bool HasMinusINF;
//	bool HasPlusINF;

//SemanticsDataType * DataType;
//GenericTable<int> * Name;
//SemanticsMethodStatementMethodCall * ConstructorInherit;
//GenericTable<SemanticsMethodValuePair> * ValuePairs;
//GenericTable<SemanticsMethodParameter> * Arguments;
//SemanticsMethodBody * MethodBody;
#ifdef DEBUG
void SemanticsMethod::DebugXMLOutput(FILE * fo)
{

	//start tag
	fprintf(fo,"<semanticsMethod name=\"");

	//GenericTable<int> * Name;
	SemanticAnalyzer::DebugOutputNameFromTable(fo, this->Name, CompilerData->Units);

	fprintf(fo, "\">\n");


	//int parentContext
	fprintf(fo,"<parentContext>%d</parentContext>\n",this->parentContext);

    
	//	bool ModifierPrivate;
	if (ModifierPrivate)
		fprintf(fo,"<modifierPrivate>true</modifierPrivate>\n");

	else
		fprintf(fo,"<modifierPrivate>false</modifierPrivate>\n");


	//	bool ModifierPublic;
	if (ModifierPublic)
		fprintf(fo,"<modifierPublic>true</modifierPublic>\n");

	else
		fprintf(fo,"<modifierPublic>false</modifierPublic>\n");
	
	
	//	bool ModifierProtected;
	if (ModifierProtected)
		fprintf(fo,"<modifierProtected>true</modifierProtected>\n");

	else
		fprintf(fo,"<modifierProtected>false</modifierProtected>\n");


	//	bool ModifierStatic;
	if (ModifierStatic)
		fprintf(fo,"<modifierStatic>true</modifierStatic>\n");

	else
		fprintf(fo,"<modifierStatic>false</modifierStatic>\n");
	
	
	//	bool ModifierAbstract;
	if (ModifierAbstract)
		fprintf(fo,"<modifierAbstract>true</modifierAbstract>\n");

	else
		fprintf(fo,"<modifierAbstract>false</modifierAbstract>\n");
	
	
	//	bool ModifierFinal;
	if (ModifierFinal)
		fprintf(fo,"<modifierFinal>true</modifierFinal>\n");

	else
		fprintf(fo,"<modifierFinal>false</modifierFinal>\n");
	
		
	//	bool ModifierVirtual;
	if (ModifierVirtual)
		fprintf(fo,"<modifierVirtual>true</modifierVirtual>\n");

	else
		fprintf(fo,"<modifierVirtual>false</modifierVirtual>\n");
	
	
	//	bool ModifierOverride;
	if (ModifierOverride)
		fprintf(fo,"<modifierOverride>true</modifierOverride>\n");

	else
		fprintf(fo,"<modifierOverride>false</modifierOverride>\n");


	//	bool IsConstructor;
	if (IsConstructor)
		fprintf(fo,"<isConstructor>true</isConstructor>\n");

	else
		fprintf(fo,"<isConstructor>false</isConstructor>\n");
	
	
	//	bool IsReadProperty;
	if (IsReadProperty)
		fprintf(fo,"<isReadProperty>true</isReadProperty>\n");

	else
		fprintf(fo,"<isReadProperty>false</isReadProperty>\n");
	
	
	//	bool IsWriteProperty;
	if (IsWriteProperty)
		fprintf(fo,"<isWriteProperty>true</isWriteProperty>\n");

	else
		fprintf(fo,"<isWriteProperty>false</isWriteProperty>\n");

	
	//	bool IsNumeric;
	if (IsNumeric)
		fprintf(fo,"<isNumeric>true</isNumeric>\n");

	else
		fprintf(fo,"<isNumeric>false</isNumeric>\n");
	
	
	//	bool IsDiscrete;
	if (IsDiscrete)
		fprintf(fo,"<isDiscrete>true</isDiscrete>\n");

	else
		fprintf(fo,"<isDiscrete>false</isDiscrete>\n");
	
	
	//	bool IsContinuous;
	if (IsContinuous)
		fprintf(fo,"<isContinuous>true</isContinuous>\n");

	else
		fprintf(fo,"<isContinuous>false</isContinuous>\n");

	
	//	bool HasMinusINF;
	if (HasMinusINF)
		fprintf(fo,"<hasMinusINF>true</hasMinusINF>\n");

	else
		fprintf(fo,"<hasMinusINF>false</hasMinusINF>\n");
	
	
	//	bool HasPlusINF;
	if (HasPlusINF)
		fprintf(fo,"<hasPlusINF>true</hasPlusINF>\n");

	else
		fprintf(fo,"<hasPlusINF>false</hasPlusINF>\n");


    /*
	if ()
		fprintf(fo,"<>true</>\n");

	else
		fprintf(fp,"<>false</>\n");

	*/


	//SemanticsDataType * DataType;
	DataType->DebugXMLOutput(fo);




	//SemanticsMethodStatementMethodCall * ConstructorInherit;
	ConstructorInherit->DebugXMLOutput(fo);


	//GenericTable<SemanticsMethodValuePair> * ValuePairs;
	fprintf(fo,"<valuePairs>\n");
	for(int i = 0; i < this->ValuePairs->GetCount(); i++)
	{
		SemanticsMethodValuePair * smvp = this->ValuePairs->GetData(i);
		smvp->DebugXMLOutput(fo);
	}
	fprintf(fo,"</valuePairs>\n");


	
	//GenericTable<SemanticsMethodParameter> * Arguments;
	fprintf(fo,"<arguments>\n");
	for(int i = 0; i < this->ValuePairs->GetCount(); i++)
	{
		SemanticsMethodParameter * smp = this->Parameters->GetData(i);
		if(smp != NULL)
		{
			// TODO: check this
			smp->DebugXMLOutput(fo);
		}
	}
	fprintf(fo,"</arguments>\n");

	
	
	//SemanticsMethodBody * MethodBody;
	MethodBody->DebugXMLOutput(fo);


    

	//end tag
	fprintf(fo,"</semanticsMethod>\n");

}
#endif


/*
#ifdef DEBUG
void TODO::DebugXMLOutput(FILE * fo){
}
#endif
*/
